using EasyAdmin.Admin.Entity.Entities;
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;

namespace EasyAdmin.Admin.Application.Services.Impl
{
    public class SysUserService : ISysUserService
    {
        private readonly ISqlSugarClient _db;
        private readonly IConfiguration _configuration;

        public SysUserService(ISqlSugarClient db, IConfiguration configuration)
        {
            _db = db;
            _configuration = configuration;
        }

        public async Task<(bool Success, string Token, string Message)> LoginAsync(string username, string password)
        {
            var user = await _db.Queryable<SysUser>()
                .FirstAsync(u => u.Username == username);

            if (user == null)
                return (false, null, "用户不存在");

            if (!BCrypt.Net.BCrypt.Verify(password, user.Password))
                return (false, null, "密码错误");

            if (user.Status != 1)
                return (false, null, "用户已被禁用");

            // 更新登录时间
            user.LastLoginTime = DateTime.Now;
            await _db.Updateable(user).UpdateColumns(u => u.LastLoginTime).ExecuteCommandAsync();

            // 生成Token
            var token = GenerateJwtToken(user);

            return (true, token, "登录成功");
        }

        public async Task<(bool Success, string Message)> CreateUserAsync(SysUser user)
        {
            var exists = await _db.Queryable<SysUser>()
                .AnyAsync(u => u.Username == user.Username);

            if (exists)
                return (false, "用户名已存在");

            user.Password = BCrypt.Net.BCrypt.HashPassword(user.Password);
            user.CreateTime = DateTime.Now;
            user.Status = 1;

            var result = await _db.Insertable(user).ExecuteCommandAsync() > 0;
            return (result, result ? "创建成功" : "创建失败");
        }

        public async Task<(bool Success, string Message)> UpdateUserAsync(SysUser user)
        {
            var exists = await _db.Queryable<SysUser>()
                .AnyAsync(u => u.Id == user.Id);

            if (!exists)
                return (false, "用户不存在");

            user.UpdateTime = DateTime.Now;
            var result = await _db.Updateable(user)
                .IgnoreColumns(u => new { u.Password, u.CreateTime })
                .ExecuteCommandAsync() > 0;

            return (result, result ? "更新成功" : "更新失败");
        }

        public async Task<(bool Success, string Message)> DeleteUserAsync(int userId)
        {
            var result = await _db.Deleteable<SysUser>()
                .Where(u => u.Id == userId)
                .ExecuteCommandAsync() > 0;

            return (result, result ? "删除成功" : "删除失败");
        }

        public async Task<SysUser> GetUserByIdAsync(int userId)
        {
            return await _db.Queryable<SysUser>()
                .FirstAsync(u => u.Id == userId);
        }



        private string GenerateJwtToken(SysUser user)
        {
            var claims = new[]
            {
                new Claim(JwtRegisteredClaimNames.Sub, user.Id.ToString()),
                new Claim(JwtRegisteredClaimNames.UniqueName, user.Username),
                new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
                new Claim("UserId", user.Id.ToString()),
                new Claim("Username", user.Username)
            };

            var key = new SymmetricSecurityKey(
                Encoding.UTF8.GetBytes(_configuration["JwtSettings:SecurityKey"]));
            var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
            var expires = DateTime.Now.AddMinutes(
                Convert.ToDouble(_configuration["JwtSettings:ExpirationMinutes"]));

            var token = new JwtSecurityToken(
                _configuration["JwtSettings:Issuer"],
                _configuration["JwtSettings:Audience"],
                claims,
                expires: expires,
                signingCredentials: creds
            );

            return new JwtSecurityTokenHandler().WriteToken(token);
        }

        public async Task<(List<SysUser> Items, int Total)> GetUserListAsync(string keyword, int pageIndex, int pageSize)
        {
            var query = _db.Queryable<SysUser>()
                .Where(u => u.IsDeleted == 0);

            if (!string.IsNullOrEmpty(keyword))
            {
                query = query.Where(u => u.Username.Contains(keyword) || 
                                        u.NickName.Contains(keyword) || 
                                        u.Mobile.Contains(keyword));
            }

            var total = await query.CountAsync();
            var items = await query
                .OrderBy(u => u.Id)
                .Skip((pageIndex - 1) * pageSize)
                .Take(pageSize)
                .ToListAsync();

            return (items, total);
        }

        /// <summary>
        /// 获取用户角色
        /// </summary>
        /// <param name="userId">用户ID</param>
        /// <returns></returns>
        public async Task<List<SysRole>> GetUserRolesAsync(int userId)
        {
            var roles = await _db.Queryable<SysUserRole>()
                .LeftJoin<SysRole>((ur, r) => ur.RoleId == r.Id)
                .Where((ur, r) => ur.UserId == userId)
                .Select((ur, r) => r)
                .ToListAsync();
            
            return roles;
        }

        /// <summary>
        /// 设置用户角色
        /// </summary>
        /// <param name="userId">用户ID</param>
        /// <param name="roleIds">角色ID列表</param>
        /// <returns></returns>
        public async Task<(bool Success, string Message)> SetUserRolesAsync(int userId, List<int> roleIds)
        {
            try
            {
                // 检查用户是否存在
                var user = await _db.Queryable<SysUser>().FirstAsync(u => u.Id == userId);
                if (user == null)
                {
                    return (false, "用户不存在");
                }

                // 删除用户原有角色
                await _db.Deleteable<SysUserRole>().Where(ur => ur.UserId == userId).ExecuteCommandAsync();

                // 添加新角色
                if (roleIds != null && roleIds.Count > 0)
                {
                    var userRoles = roleIds.Select(roleId => new SysUserRole
                    {
                        UserId = userId,
                        RoleId = roleId
                    }).ToList();

                    await _db.Insertable(userRoles).ExecuteCommandAsync();
                }

                return (true, "设置用户角色成功");
            }
            catch (Exception ex)
            {
                return (false, $"设置用户角色失败：{ex.Message}");
            }
        }
    }
}